php中的路径研究和./ ../ __DIR__ __FILE__ getcwd() 的用法和区别

当前环境是mac,项目目录是/web/
路径的问题特别容易混淆,特别是在include和require_once或者file_get_content()的时候,
view里面展示图片也会出现路径错误的问题

.表示当前目录
..表示当前目录的上一级目录。
./表示当前目录下的某个文件或文件夹,
../表示当前目录上一级目录的文件或文件夹

先简单举个例子

index.html中引用css

当前目录(b)下的css文件夹

1
<link rel="stylesheet" href='css/main.css'/>

1
<link rel="stylesheet" href='./css/main.css'/>

再或者是
当前目录的上级目录(demo)下的b目录下的css目录

1
<link rel="stylesheet" href='../b/css/main.css'/>

使用图片

1
2
<img src="test2.jpg">
<img src="../a/test1.jpg">

类似php中也是
在index.php中

1
2
3
require_once "c/user.php";
//或者
require_once "./c/user.php";

在user.php中

1
require_once "../index.php";

getcwd() :在哪个文件里调用此文件的目录

__DIR__ : 当前内容写在哪个文件的目录

__FILE__ :当前内容写在哪个文件的目录+文件名

有个问题在项目中很容易出错

我们经常会在项目中require或者include引用某个php文件

以yii基础版框架随便举个例子
运行UserController的actionList
localhost/demo/web/index.php?r=admin/user/list

在UserController中

1
2
3
4
5
6
7
8
echo __DIR__;  
// 当前内容写在哪个文件(UserController.php)的目录admin
// /web/demo/controllers/admin
echo __FILE__;
// /web/demo/controllers/admin/UserController.php
echo getcwd();
// 在入口文件index.php中调用的此文件,所以是index.php的目录
// /web/demo/web

然后我们在UserController.php中require_once submit.php
我们可能会跟上面的例子那样,以当前文件为基准去写相对路径

1
require_once "../../alipay/lib/submit.php"

然后我们运行,却发现报错了
Failed opening required '../../alipay/lib/submit.php

“UserController.php所在目录(admin)的上级目录(controllers)的上级目录(demo)下面的alipay下面的lib”
“对啊,../../没错啊”

仔细思考后 我们的url localhost/demo/web/index.php?r=admin/user/list
我们这里的相对路径是以index.php为基准的

所以这里我们应该这么写

1
require_once "../alipay/lib/submit.php"

运行发现成功

其实这里也可以这么写相对路径

1
2
3
4
5
6
7
// index.php文件所在目录(web)的上级目录(demo)下的alipay
require_once getcwd()."/../alipay/lib/submit.php"

// 或者

// 当前文件目录(admin)的上级目录(controllers)的上级目录(demo)下的alipay
require_once __DIR__."/../../alipay/lib/submit.php"

如果我们在入口文件(index.php)定义一个全局的变量

1
define('BASE_PATH', str_replace('\\', '/', realpath(dirname(__FILE__) . '/../')));

不管在哪里

1
echo BASE_PATH

都会输出我们的根目录
/web/demo

那么刚才的可以写成绝对路径

1
require_once BASE_PATH."/alipay/lib/submit.php"

这样代码迁移起来也更方便